home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 007 / braces.arc / BRACES.M < prev   
Encoding:
Text File  |  1987-05-25  |  3.3 KB  |  154 lines

  1. ; ** BRACES.M
  2.  
  3. ; ** This macro examines the character at the cursor. If it is any of the
  4. ; ** 4 characters (){} it tries to find the matching character. For C programs
  5. ; ** it correctly handles comments, and string and character constants.
  6.  
  7. (macro braces
  8.     (
  9.         (int    dir        ; ** 1 = forward, 0 = backward
  10.                 lev        ; ** search level
  11.                 cod        ; ** search return code
  12.         )
  13.         (string    target    ; ** search string
  14.                 skip    ; ** used to skip strings and comments
  15.         )
  16.         ; ** determine search argument and direction
  17.         (= lev 1)
  18.         (if (== "(" (= target (read 1) ) )
  19.             (
  20.                 (= target "[))((\"']|{/\\*}")
  21.                 (= dir 1)
  22.             )
  23.             ;else
  24.             (if (== target "{")
  25.                 (
  26.                     (= target "[\\}\\{\"']|{/\\*}")
  27.                     (= dir 1)
  28.                 )
  29.                 ;else
  30.                 (if (== target ")")
  31.                     (
  32.                         (= target "[(())\"']|{\\*/}")
  33.                         (= dir 0)
  34.                     )
  35.                     ;else
  36.                     (if (== target "}")
  37.                         (
  38.                             (= target "[\\{\\}\"']|{\\*/}")
  39.                             (= dir 0)
  40.                         )
  41.                         ;else
  42.                         (= lev -2)
  43.                     )
  44.                 )
  45.             )
  46.         )
  47.         ; ** search loop
  48.         (message "Searching...")
  49.         (while (> lev 0)
  50.             (
  51.                 ; ** next search
  52.                 (if (> dir 0)
  53.                     (
  54.                         (next_char)
  55.                         (= cod (search_fwd target) )
  56.                     )
  57.                     ;else
  58.                     (if (_can_rev 1)
  59.                         (= cod (search_back target) )
  60.                         ;else
  61.                         (= cod 0)
  62.                     )
  63.                 )
  64.                 ; ** handle search results
  65.                 (if (> cod 0)
  66.                     (
  67.                         (= cod (index target (read 1) ) )
  68.                         (if (< cod 4) 
  69.                             (= lev (- lev 1) )    ; ** opposite pair
  70.                             ;else
  71.                             (if (< cod 6)
  72.                                 (= lev (+ lev 1) )    ; ** same guy
  73.                                 ;else        ; ** must bypass something
  74.                                 (
  75.                                     ; ** setup for bypass
  76.                                     (if (== cod 6)
  77.                                         (= skip "[~\\\\]\\c\"" )
  78.                                         ;else
  79.                                         (if (== cod 7)
  80.                                             (= skip "[~\\\\]\\c'" )
  81.                                             ;else
  82.                                             (if (> dir 0)
  83.                                                 (
  84.                                                     (= skip "\\*/")
  85.                                                     (next_char)
  86.                                                     (next_char)
  87.                                                 )
  88.                                                 ;else
  89.                                                 (= skip "/\\*")
  90.                                             )
  91.                                         )
  92.                                     )
  93.                                     ; ** try and bypass
  94.                                     (if (> dir 0)
  95.                                         (= cod (search_fwd skip) )
  96.                                         ;else
  97.                                         (if (_can_rev 2)
  98.                                             (= cod (search_back skip) )
  99.                                             ;else
  100.                                             (= cod 0)
  101.                                         )
  102.                                     )
  103.                                 )
  104.                             )
  105.                         )
  106.                     )
  107.                 )
  108.                 (if (< cod 1)
  109.                     (= lev -1)                ; ** search failed
  110.                 )
  111.             )
  112.         )
  113.         (refresh)                            ; ** show where we are
  114.         (if (== lev 0)
  115.             (message "Match found.")
  116.             ;else
  117.             (
  118.                 (if (== lev -1)
  119.                     (message "No Match.")
  120.                     ;else
  121.                     (message "Invalid: must be {, }, ( or ).")
  122.                 )
  123.                 (beep)                        ; ** signal error
  124.             )
  125.         )
  126.     )
  127. )
  128.  
  129. ; ** this macro is used to determine whether or not a reverse search is
  130. ; ** possible. it attempts to prev_char <parameter> number of times.
  131. ; ** it returns 0 if the reversing was not successful (top of buffer).
  132.  
  133. (macro _can_rev
  134.     (
  135.         (int    cnt        ; ** reverse count
  136.                 lin        ; ** current line number
  137.                 col        ; ** current column number
  138.         )
  139.         (get_parm 0 cnt)                    ; ** number of prev_char(s)
  140.         (while (> cnt 0)
  141.             (
  142.                 (inq_position lin col)                ; ** where am i?
  143.                 (prev_char)                            ; ** try to back up
  144.                 (= cnt (- cnt 1) )                    ; ** decrement count
  145.                 (if (&& (== lin 1) (== col 1) )
  146.                     (returns 0)                          ; ** top of buffer
  147.                     ;else
  148.                     (returns 1)                        ; ** elsewhere
  149.                 )
  150.             )
  151.         )
  152.     )
  153. )
  154.